<script>
//TODO 暂未做取消请求和进度条
import { getImgById } from '@/directive/img-auth';

function getIdsList(ids) {
    // 使用空格或者换行分割
    return ids.split(/[\s\n]/).filter(item => item);
}

// 可中断promise
function abortWrapper(promiseOrigin) {
    // 声明中断函数
    let abortFunc;
    // 中断函数等于promise的reject
    let promiseAbort = new Promise((resolve, reject) => (abortFunc = reject));
    let resultPromise = Promise.race([promiseAbort, promiseOrigin]);
    // 将中断函数挂载到promise上
    resultPromise.abort = abortFunc;
    return resultPromise;
}

export default {
    data() {
        return {
            ids: '',
            imgList: [],
            size: 0,
            count: 0,
            req: null
        };
    },
    methods: {
        parseImg() {
            if (this.req !== null) {
                this.$Message.error('当前有请求正在进行中');
                return;
            }


            this.$Message.loading({
                render: h => {
                    return h('div', [h('span', `已加载${this.count}/${this.size}`), h('i', { class: 'el-icon-loading' })]);
                },
                duration: 0
            });
            const ids = getIdsList(this.ids);
            this.size = ids.length;
            this.count;
            this.imgList = new Array(ids.length).fill('');
            let funList = ids.map((item, index) => {
                return this.handleImg(item, index);
            });
            let res = abortWrapper(Promise.allSettled(funList));
            this.req = res;
            res.then(res => {
                // 错误列表
                let errIds = [];
                if (Array.isArray(res)) {
                    res.forEach((item, index) => {
                        if (item.status === 'rejected') {
                            errIds.push(ids[index]);
                        }
                    });
                }
                this.$Message.destroy();
                if (errIds.length) {
                    this.$Message.error(`id为${errIds.join(',')}的图片加载失败`);
                    this.req = null;
                } else {
                    this.$Message.success('图片加载成功', 0);
                    this.req = null;
                }
            });
        },
        async handleImg(id, index) {
            try {
                const res = await getImgById(id);
                this.imgList.splice(index, 1, res);
                this.count++;
            } catch (e) {
                this.imgList.splice(index, 1, '出错了');
                throw e;
            }
        }
    },
    destroyed() {
        this.$Message.destroy();
    }
};
</script>

<template>
    <div class="box">
        <div class="data-input">
            <el-input type="textarea" placeholder="请输入id列表" v-model="ids" rows="15" resize="none"></el-input>
            <div>
                <el-row>
                    <el-button type="primary" @click="parseImg">解析图片</el-button>
                </el-row>
            </div>
        </div>
        <div class="data-view">
            <div v-for="item in imgList">
                <el-image fit="cover" v-if="item !== '出错了'" class="imgBox" :src="item" :preview-src-list="imgList">
                    <div slot="error" class="d-flex-align-center justify-content-center h-100">
                        <i class="el-icon-picture-outline"></i>
                        加载中
                    </div>
                </el-image>
                <div v-else class="imgBox">出错了</div>
            </div>
        </div>
    </div>
</template>

<style scoped lang="less">
.box {
    background-color: white;
    width: 100%;
    min-height: 80vh;
    overflow: auto;
}
/*上部*/
.data-input {
    padding: 20px;
    height: 400px;
    display: flex;
    div {
        flex: 1;
    }
    div:nth-child(1) {
        height: 100%;
        font-size: 16px;
    }
    div:nth-child(2) {
        padding-left: 20px;
    }
}
.data-view {
    padding: 20px;
    overflow: auto;
    display: flex;
    align-items: start;
    flex-wrap: wrap;
    > div {
        margin-right: 20px;
        margin-bottom: 20px;
    }
    .imgBox {
        width: 300px;
        height: 300px;
        display: flex;
        justify-content: center;
        align-items: center;
    }
}
</style>
